/**
 * 模块二： ES 新特性与TypeScript、JS性能优化
 */


 
 /**
  * 一、简答题：请说出下列最终执行结果，并解释为什么
  */

  var a = [];
  for ( var i = 0; i < 10; i++){
    a[i] = function(){
        console.log(i);
    }
  }
  a[6]()

/*********************** 答题 ********************/
// 最终执行结果为 10 ，因为i处于for循环的判断条件定义中，它的作用域是全局作用域；
// 而且a[6]的执行处于，for循环执行完，i已经变10的时候，所以打印的结果会是10



/**
  * 二、请说出下列最终执行结果，并解释为什么
  */

  var tmp = 123;
  if(true){
    console.log(tmp);
    let tmp
  }
/*********************** 答题 ********************/
//会报错，因为 if 语句内部有声明 tmp 变量，所以不会有变量提升；而ES6规定用 let 声明的变量的调用必须在声明之后，否则会报错



/**
 * 三、结合ES6新语法，用最简单的方式找出数组中的最小值
 */

 var arr = [12, 34, 32, 89, 4]

/*********************** 答题 ********************/
let min = Math.min(...arr)
console.log(min);



/**
 * 四、请详细说明 var, let，const 三种声明变量的方式之间的具体差别
 */

/*********************** 答题 ********************/
// var: ES6 之前声明变量的方式，只有全局作用域和函数作用域，存在变量提升现象（函数中找不到的变量会往上搜索全局变量是否有，有的话就使用全局的同名变量）
// let: ES6 新增的变量声明方式，有块级作用域的概念；嵌套块级作用域中可以使用 let 命名相同名字的变量，子作用域中的值并不会被父级作用域的值所覆盖
// const: ES6 新增常量声明方式
// var 在变量声明之前调用，返回undefined; 而 let 只能先声明后调用，否则会报错；var 存在变量提升，而 let、const 不存在



/**
 * 五、请说出下列最终执行结果，并解释为什么
 */

var a = 10;
var obj = {
    a: 20,
    fn(){
        setTimeout(() => {
            console.log(this.a)
        })
    }
}
obj.fn()

/*********************** 答题 ********************/
//输出20，obj内部的this指向的是obj本身，fn的定义方式并非箭头函数，所以fn内部的this也会指向obj; fn 内部的 setTimeout 内部函数定义使用了箭头函数，
//箭头函数会将setTimeout函数内部的this指向 fn 的this,也就是obj的this; 而obj 的this.a = 20



/**
 * 六、简述 Symbol 类型的用途 
 */
/*********************** 答题 ********************/
//Symbol可同样用于对象属性的定义和访问; 在给对象添加属性时，属性名都是字符串，容易重名，如果使用Symbol，则能添加独一无二的属性名
//Symbol类型的key是不能通过Object.keys()或者for...in来枚举的,利用该特性，我们可以把一些不需要对外操作和访问的属性使用Symbol来定义



/**
 * 七、说说什么是浅拷贝，什么是深拷贝 
 */
/*********************** 答题 ********************/
//浅拷贝：对基本数据类型时进行值拷贝，修改原变量不会引起拷贝对象值改变；而对引用数据类型只是拷贝了访问地址，原对象变量的改变会影响到拷贝变量的改变
//深拷贝：不管基础数据类型还是引用数据类型都是，原变量的改变不会影响到拷贝变量的内容



/**
 * 八、请简述 TypeScript 与 JavaScript 之间的关系 
 */
/*********************** 答题 ********************/
//TypeScript 是 JavaScript 的超集, TypeScript 实现了 ECMAScript 的新特性
//typescript 拥有更强大的类型系统，以及对 ECMAscript 新特性的支持，写完的代码可以编译成能在生产环境直接运行的 javascript
//typescript 的类型系统跟 javascript 的 flow 一样
//任何javascript 的运行环境都可以用 typescript 去开发，web 、node、react-native 等



/**
 * 九、请谈谈你所认为的 TypeScript 的优缺点 
 */
/*********************** 答题 ********************/
//优点一：typescript 拥有更强大的类型系统，以及对 ECMAscript 新特性的支持，写完的代码可以编译成能在生产环境直接运行的 javascript
//优点二：vscode 里面使用 javascript flow 会迟钝，vscode 直接使用 typescript 就会很流畅
//优点三：增强代码的可读性和可维护性，在编译时即可发现大部分的错误，提升编码效率

//缺点一：短期增加开发成本，增加类型定义，但减少维护成本；小型且不需持续维护项目使用 js 比使用 ts 开发效率高
//缺点二：ts 集成到构建流程需要一定的工作量，需要根据需要灵活配置相关类型定义



/**
 * 十、描述引用计数的工作原理和优缺点
 */
/*********************** 答题 ********************/
//原理：设置引用数，判断当前引用数是否为0；引用关系改变时修改引用数字；引用数字为 0 时立即回收
//优点：发现垃圾时立即回收；最大限度减少程序暂停
//缺点：无法回收循环引用的对象；时间开销大



/**
 * 十一、描述标记整理算法的工作流程
 */
/*********************** 答题 ********************/
//分成标记和清除二个阶段完成；遍历所有对象找标记活动对象；遍历所有对象清除没有标记对象；清除的同时会先执行整理，移动活动对象位置；



/**
 * 十二、描述V8中新生代存储区垃圾回收的流程
 */
/*********************** 答题 ********************/
//内存一分为二；
//小空间用于存储新生代对象（32M|16M）；回收过程采用复制算法 + 标记整理；新生代空间为 From ,空闲空间为 To （等大小）；活动对象存储于 From 空间；标记整理后将活动对象拷贝至 To （From 空间完全释放）；From 与 To 交换空间完成释放 （回收后 From 空间是连续的）；拷贝过程中可能出现晋升；晋升就是将新生代对象移动至老生代：① 一轮 GC 还存活的新生代需要晋升，需要晋升的情况有两种： ② 拷贝过程中，To 空间的使用率超过 25%
//老生代对象存放在老生代区域；64bit 操作系统 1.4G, 32bit 操作系统 700M；主要采用标记清除、标记整理、增量标记算法；首先使用标记清除完成垃圾空间的回收；采用标记整理进行空间优化：当新生代对象晋升到老生代时，而且老生代存储空间又不足以新生代晋升使用时，触发标记整理；采用增量标记进行效率优化：主程序和清除标记程序交替进行



/**
 * 十三、描述增量标记算法在何时使用及工作原理
 */
/*********************** 答题 ********************/
//何时使用：V8中老生代存储区垃圾回收时采用增量标记进行效率优化
//工作原理：主程序和清除标记程序交替进行